package com.xixing.weixin.cmd;

import com.xixing.weixin.exception.ArgumentException;
import com.xixing.weixin.domain.Weixin;
import com.xixing.weixin.response.Response;
import com.xixing.weixin.response.TextResponse;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ResourceBundle;

/**
 * 基本的执行器.
 * 1. 从配置文件中读取信息，初始化commandName, alias,help;
 * 2. 基本的帮助方法.
 * 3. 基本的接口实现.
 *
 */
public abstract class AbstractExecutor implements Executor {
    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractExecutor.class);
    protected static ResourceBundle resourceBundle = ResourceBundle.getBundle("command");



    private String commandName;
    private String[] alias;
    private String help;


    protected AbstractExecutor() {
        String key = null;
        try {
            key = this.getClass().getSimpleName() + ".commandName";
            setCommandName(normalCommand(resourceBundle.getString(key)));
        } catch (Exception e) {
            LOGGER.warn("No Property : {}" + key);
        }

        try {
            key = this.getClass().getSimpleName() + ".alias";
            setAliasName(normalCommand(resourceBundle.getString(key)));
        } catch (Exception e) {
            LOGGER.warn("No Property : {}" + key);
        }

        try {
            key = this.getClass().getSimpleName() + ".help";
            setHelp(resourceBundle.getString(key));
        } catch (Exception e) {
            LOGGER.warn("No Property : {}" + key);
        }


    }

    // 分解命令和参数.
    public static String[] splitCommand(String command) {
        return command.split(",| ");
    }

    // 预处理命令.
    public static String normalCommand(String commandName) {
        if (commandName == null) return null;
        return commandName.toUpperCase();
    }

    public String getCommandName() {
        return commandName;
    }

    public void setCommandName(String commandName) {
        this.commandName = commandName;
    }

    public String[] getAlias() {
        return alias;
    }

    public void setAlias(String[] alias) {
        this.alias = alias;
    }

    public void setAliasName(String alias) {
        if (alias == null) {
            this.alias = null;
        }
        this.alias = splitCommand(alias);
    }

    public String getHelp() {
        return help;
    }

    public void setHelp(String help) {
        this.help = help;
    }


    @Override
    public boolean isCommand(String command) {
        String cmd = normalCommand(command);
        if (commandName.equals(cmd)) return true;
        if (alias != null)
            if (ArrayUtils.contains(alias, cmd)) return true;
        return false;
    }

    @Override
    public Response help(Weixin weixin, Object args) {
        return  TextResponse.create(weixin, getHelp());
    }

    protected void assertWeixinMsgType(Weixin weixin, String text) throws ArgumentException {
        if(!text.equals(weixin.getMsgType())) throw new ArgumentException(getHelp());
    }

    protected void assertWeixinContentLength(Weixin weixin, int min, int max) throws ArgumentException {
        String[] cmds = splitCommand(weixin.getContent());
        if(cmds.length < min) throw new ArgumentException(getHelp());
        if(cmds.length > max) throw new ArgumentException(getHelp());
    }

    protected void assertBetween(int value, int min, int max) throws ArgumentException {
        if(value < min || value > max) throw new ArgumentException(getHelp());
    }
}
